﻿using AutoMapper;
using Furion;
using Furion.DependencyInjection;
using Furion.LinqBuilder;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using XinGuanERP.Db;
using XinGuanERP.Models.Po.system;
using XinGuanERP.Models.Vo.system;
using XinGuanERP.Services.system.IServices;
using XinGuanERP.Utils;

namespace XinGuanERP.Services.system
{
    public class DictEntryService : IDictEntryService, ITransient
    {
        private readonly DefaultDbContext _defaultDbContext;
        public DictEntryService(DefaultDbContext defaultDbContext)
        {
            _defaultDbContext = defaultDbContext;
        }
        public bool DeleteDictEntry(string Id)
        {
            var res = _defaultDbContext.DictEntries.FirstOrDefault(de => de.Id == Id);
            if (res != null)
            {
                _defaultDbContext.DictEntries.Remove(res);
                return _defaultDbContext.SaveChanges() > 0;
            }
            else
            {
                return false;
            }
        }

        public PageResult<DictEntryVo> GetDictEntryWithPage(int page, int pageSize, string? DictId, string? Label)
        {
            var res = new List<DictEntry>();
            var count = 0;
            var sql = _defaultDbContext.DictEntries.Include(de => de.Dict).OrderBy(de => de.OrderSort).AsQueryable();
            if (!DictId.IsNullOrEmpty())
            {
                sql = sql.Where(de => de.DictId == DictId).AsQueryable();
                if (!Label.IsNullOrEmpty())
                {
                    res = sql.Where(de =>
                            EF.Functions.Like(de.Label, "%" + Label + "%"))
                        .Skip((page - 1) * pageSize).Take(pageSize).ToList();
                    count = sql.Where(de =>
                            EF.Functions.Like(de.Label, "%" + Label + "%"))
                        .Count();
                }
                else
                {
                    res = sql.Skip((page - 1) * pageSize).Take(pageSize).ToList();
                    count = sql.Count();
                }
            }
            else
            {
                if (!Label.IsNullOrEmpty())
                {
                    res = sql.Where(de =>
                            EF.Functions.Like(de.Label, "%" + Label + "%"))
                        .Skip((page - 1) * pageSize).Take(pageSize).ToList();
                    count = sql
                        .Count(de => EF.Functions.Like(de.Label, "%" + Label + "%"));
                }
                else
                {
                    res = sql.Skip((page - 1) * pageSize).Take(pageSize).ToList();
                    count = sql.Count();
                }
            }

            List<DictEntryVo> viewDictEntries = new();
            var config = new MapperConfiguration(cfg => cfg.CreateMap<DictEntry, DictEntryVo>()
                .ForMember(dest => dest.DictName, opt => opt.MapFrom(src => src.Dict.Name))
                .ForMember(dest => dest.DictCode, opt => opt.MapFrom(src => src.Dict.Code)));
            var mapper = config.CreateMapper();
            foreach (var dictEntry in res)
            {
                viewDictEntries.Add(
                        mapper.Map<DictEntryVo>(dictEntry)
                    );
            }

            return new PageResult<DictEntryVo>()
            {
                Items = viewDictEntries,
                Total = count
            };
        }

        public List<DictEntryVo> GetDictEntryWithListByDictCode(string dictCode)
        {
            var res = _defaultDbContext.DictEntries
            .Where(de => de.DictId == 
                _defaultDbContext.Dicts.Where(d => d.Code == dictCode).Select(d => d.Id).FirstOrDefault())
            .OrderBy(de => de.OrderSort).ToList();
            var config = new MapperConfiguration(cfg => cfg.CreateMap<DictEntry, DictEntryVo>());
            var mapper = config.CreateMapper();
            List<DictEntryVo> viewDictEntries = new();
            foreach (var dictEntry in res)
            {
                viewDictEntries.Add(mapper.Map<DictEntryVo>(dictEntry));
            }

            return viewDictEntries;
        }

        public bool UpdateDictEntry(DictEntryVo viewDictEntry)
        {
            var res = _defaultDbContext.DictEntries.FirstOrDefault(de => de.Id == viewDictEntry.Id);
            var config = new MapperConfiguration(cfg => cfg.CreateMap<DictEntryVo, DictEntry>()
                .BeforeMap((src, des) => src.Id = Guid.NewGuid().ToString().Replace("-", "").ToUpper())
                .BeforeMap((src, des) => des.CreateTime = DateTime.Now)
                .BeforeMap((src, des) => des.CreateUserId = App.User?.FindFirstValue("UserId"))
                .BeforeMap((src, des) => des.CreateUserName = App.User?.FindFirstValue("UserName")));
            var mapper = config.CreateMapper();
            if (res == null)
            {
                var des = mapper.Map<DictEntry>(viewDictEntry);
                _defaultDbContext.DictEntries.Add(
                    des
                );
            }
            else
            {
                res = new MapperConfiguration(cfg => cfg.CreateMap<DictEntryVo, DictEntry>()
                        .BeforeMap((src, des) => des.UpdateTime = DateTime.Now)
                        .BeforeMap((src, des) =>
                            des.UpdateUserId = App.User?.FindFirstValue("UserId"))
                        .BeforeMap((src, des) =>
                            des.UpdateUserName = App.User?.FindFirstValue("UserName")))
                    .CreateMapper().Map(viewDictEntry, res);
            }

            return _defaultDbContext.SaveChanges() > 0;
        }
    }
}
